using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Xml;
using System.Xml.Linq;
using Lucene.Net.Analysis;
using Lucene.Net.Store;
using MvcContrib.ActionResults;
using WWB.SitePointPrivateMessages.Core.Infrastructure.Logging;
using WWB.SitePointPrivateMessages.Core.Model.DataImport;
using WWB.SitePointPrivateMessages.Core.Model.Messages;
using WWB.SitePointPrivateMessages.Core.Service;
using WWB.SitePointPrivateMessages.Web.Models;

namespace WWB.SitePointPrivateMessages.Web.Controllers
{
    public class MessagesController : SpPmControllerBase
    {
        [HttpGet]
        public ActionResult Index(MessageSearchFormOptions opts)
        {
            if (CurrentMessageDb == null)
            {
                return RedirectToAction("Index", "Home");
            }
            if (opts == null || opts.IsEmpty)
            {
                return View(new MessageSearchViewData(CurrentMessageDb, CurrentMessageDb.Messages));
            }
            var sm = CurrentMessageDb.SearchMessages(opts.SearchTerm, opts.SelectedFolders, opts.SelectedUsers);
            return View(new MessageSearchViewData(CurrentMessageDb, sm, opts));
        }

        [HttpGet]
        public ActionResult Message(string id)
        {
            if (CurrentMessageDb == null)
            {
                ErrorMessage = "No current message db!";
                return RedirectToAction("Index", "Home");
            }
            var m = CurrentMessageDb.Messages.FirstOrDefault(x => x.FingerPrint == id);
            if (m == null)
            {
                return View("NoSuchMessage");
            }
            return View(new MessageDetailsViewData(m));
        }

        [HttpPost]
        public ActionResult ImportMessages(HttpPostedFileBase messageFile, string errorReturnUrl)
        {
            if (messageFile == null)
            {
                throw new ArgumentOutOfRangeException("messageFile", "MessageFile is null");
            }
            var logger = new StringLogger();
            var xtr = new XmlTextReader(messageFile.InputStream);
            var svc = new XmlFileImportExportService();
            var msgExport = svc.GetMessagesFromXml(xtr);
            CurrentDirectory = new RAMDirectory();
            CurrentAnalyzer = new SimpleAnalyzer();
            LuceneMessageSearcher lms = new LuceneMessageSearcher(CurrentDirectory, CurrentAnalyzer);
            CurrentMessageDb = msgExport.ImportMessages(lms, logger);
            return RedirectToRoute(new {action = "Index", controller = "Messages"});
        }

        [HttpPost]
        public ActionResult Export(string Export_All_Imported, string Export_All_Visible, string Export_Selected, MessageExportOption[] Msg)
        {
            if (!string.IsNullOrEmpty(Export_All_Imported))
            {
                var export = CurrentMessageDb.ExportMessages(new StringLogger());
                XmlFileImportExportService fs = new XmlFileImportExportService();
                var doc = fs.SerializeMessages(export);
                return downloadXmlResult(doc, "FullExport.xml");
            }
            IEnumerable<PrivateMessage> messagesToExport = null;
            if (!string.IsNullOrEmpty(Export_All_Visible))
            {
                messagesToExport =
                    Msg.Select(opt => CurrentMessageDb.Messages.FirstOrDefault(x => x.FingerPrint == opt.FingerPrint));
            }
            //export selected clicked
            if (!string.IsNullOrEmpty(Export_Selected))
            {
                messagesToExport =
                    Msg.Where(x => x.Action).Select(
                        opt => 
                        CurrentMessageDb.Messages.FirstOrDefault(x => x.FingerPrint == opt.FingerPrint));
            }
            StringLogger sl = new StringLogger();
            var exportmsg = new List<ExportedMessage>();
            foreach (var privateMessage in messagesToExport)
            {
                exportmsg.Add(privateMessage.ConvertToExport(sl));
            }
            var ef = new ExportedFolder {Name = "Exported", Messages = exportmsg.ToArray()};
            var msgexp = new SitePointMessageExport();
            msgexp.Folders = new []{ef};
            var fileSvc = new XmlFileImportExportService();
            var xml =  fileSvc.SerializeMessages(msgexp);
            return downloadXmlResult(xml, "Export.xml");
        }

        private FileResult downloadXmlResult(XDocument doc, string fileName)
        {
            if (doc == null) throw new ArgumentNullException("doc");
            var ms = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(doc.ToString()));
            return File(ms, "text/xml", fileName);
        }
    }
}